package com.xmb.wcapi.controller;


import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xmb.wcapi.cache.CommonCache;
import com.xmb.wcapi.constant.BaseEntry;
import com.xmb.wcapi.constant.DefaultValueConstant;
import com.xmb.wcapi.constant.MaterialTypeConstant;
import com.xmb.wcapi.constant.R;
import com.xmb.wcapi.entity.*;
import com.xmb.wcapi.mapper.BaseMaterialMapper;
import com.xmb.wcapi.service.IBaseMaterialService;
import com.xmb.wcapi.service.IInitialStockService;
import com.xmb.wcapi.service.IInitialStockUploadService;
import com.xmb.wcapi.service.IStockNowService;
import com.xmb.wcapi.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 半成品期初库表 前端控制器
 * </p>
 *
 * @author huangping
 * @since 2024-07-24
 */
@Slf4j
@Controller
@RequestMapping("/initial-stock")
public class InitialStockController {

    @Resource
    IInitialStockService stockService;

    @Resource
    IStockNowService iStockNowService;

    @Autowired
    public CommonCache commonCache;

    @Autowired
    private BaseMaterialMapper baseMaterialMapper;

    @Resource
    private IInitialStockUploadService iInitialStockUploadService;

    @PostMapping("/add")
    @ResponseBody
    public R add(String url, String obj) {
        try {
            BaseEntry baseEntry = commonCache.init(url);
            setObj(baseEntry,obj);
            IService<Object> iService = baseEntry.getIService();
            List<BaseCommonDataDictionaryAndSet> collect = baseEntry.getSetList().stream().filter(e -> e.getUniqueness()).collect(Collectors.toList());
            if(collect.size() > 0){
                QueryWrapper<Object> ew = new QueryWrapper<>();
                for(BaseCommonDataDictionaryAndSet set : collect){
                    ew.eq(set.getTableField(), com.xmb.wcapi.util.BeanUtil.getMethod(baseEntry.getData(), set.getEntityField()));
                }
                Object object = iService.getOne(ew);
                if(object != null) {
                    return R.error("请勿重复添加");
                }
            }
            for(BaseCommonDataDictionaryAndSet set : baseEntry.getSetList()){
                if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(set.getDefaultValue())){
                    if(set.getDefaultValue().equals(DefaultValueConstant.user.getCode())){
                        com.xmb.wcapi.util.BeanUtil.setMethod(baseEntry.getData(), set.getEntityField(), ShiroUtil.getUserId());
                    }else if(set.getDefaultValue().equals(DefaultValueConstant.date.getCode())){
                        com.xmb.wcapi.util.BeanUtil.setMethod(baseEntry.getData(), set.getEntityField(), new Date());
                    }else if(set.getDefaultValue().equals(DefaultValueConstant.disable.getCode())){
                        BeanUtil.setMethod(baseEntry.getData(), set.getEntityField(), false);
                    }
                }
            }

            iService.save(baseEntry.getData());

            //添加结存记录
            InitialStock bean = cn.hutool.core.bean.BeanUtil.toBean(baseEntry.getData(), InitialStock.class);
            StockNow stockNow = new StockNow();
            stockNow.setMaterial(bean.getDjMaterial());
            stockNow.setTimes(DateUtil.yesterday());
            stockNow.setCreateTime(new Date());
            stockNow.setMaterialSum(bean.getInvSum().longValue());
            //先查询是否存在现存量
            List<StockNow> list = iStockNowService.list(Wrappers.lambdaQuery(StockNow.class).eq(StockNow::getMaterial, bean.getDjMaterial()));
            if (!list.isEmpty()){
                StockNow stockNow1 = list.get(0);
                stockNow1.setMaterialSum(stockNow.getMaterialSum()+stockNow1.getMaterialSum());
                iStockNowService.updateById(stockNow1);
            }else {
                iStockNowService.save(stockNow);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("系统异常");
        }
        return R.ok();
    }

    @PostMapping("/update")
    @ResponseBody
    public R update(String url, String obj) {
        try {
            BaseEntry baseEntry = commonCache.init(url);
            setObj(baseEntry,obj);
            IService<Object> iService = baseEntry.getIService();
            List<BaseCommonDataDictionaryAndSet> collect = baseEntry.getSetList().stream().filter(e -> e.getUniqueness()).collect(Collectors.toList());
            if(collect.size() > 0){
                QueryWrapper<Object> ew = new QueryWrapper<>();
                for(BaseCommonDataDictionaryAndSet set : collect){
                    ew.eq(set.getTableField(), BeanUtil.getMethod(baseEntry.getData(), set.getEntityField()));
                }
                Object object = iService.getOne(ew);
                if(object != null && !BeanUtil.getMethod(object, "id").equals(BeanUtil.getMethod(baseEntry.getData(), "id"))) {
                    return R.error("唯一性冲突");
                }
            }
            iService.updateById(baseEntry.getData());

            // 修改或者更新现存量
            InitialStock bean = cn.hutool.core.bean.BeanUtil.toBean(baseEntry.getData(), InitialStock.class);
            List<StockNow> list = iStockNowService.list(Wrappers.lambdaQuery(StockNow.class).eq(StockNow::getMaterial, bean.getDjMaterial()));
            if (!list.isEmpty()){
                StockNow stockNow = list.get(0);
                if (stockNow.getMaterialSum() > bean.getInvSum().longValue()){
                    stockNow.setMaterialSum(stockNow.getMaterialSum() - bean.getInvSum().longValue());
                }else {
                    stockNow.setMaterialSum(bean.getInvSum().longValue() - stockNow.getMaterialSum());
                }
                iStockNowService.updateById(stockNow);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("系统异常");
        }
        return R.ok();
    }


    @RequestMapping("/upload/{type}")
    @ResponseBody
    public R upload(@PathVariable("type") String type,String data){
        if (StringUtils.isEmpty(data)){
            return R.error("未读取到数据");
        }
        //数据解析
        List<InitialStockUpload> list = JSONUtil.toList(data, InitialStockUpload.class);
        if (!list.isEmpty()){
            iInitialStockUploadService.remove(Wrappers.lambdaQuery(InitialStockUpload.class));
            iInitialStockUploadService.saveBatch(list);
            //查询导入的数据
            list = iInitialStockUploadService.myBaseJoinAll();
            Map<String, Integer> initStockMap = list.stream().collect(Collectors.groupingBy(InitialStockUpload::getDjMaterial, Collectors.summingInt(InitialStockUpload::getInvSum)));
            //查询物料编码是否存在
            List<BaseMaterial> materialList = baseMaterialMapper.selectList(Wrappers.lambdaQuery(BaseMaterial.class)
                    .in(BaseMaterial::getDjMaterial, initStockMap.keySet())
                    .eq(BaseMaterial::getClassType,"B")
            );
            int count = 0;
            for (BaseMaterial material : materialList) {
                Integer maSum = initStockMap.get(material.getDjMaterial());
                if (maSum!= null){
                    //判断是否勾选
                    if (!material.isChecked()) {
                        count++;
                        boolean mark = true;
                        Integer nextSum = maSum;
                        String allBomId = material.getBomId();
                        while (mark){
                            //获取前制程物料
                            List<BaseMaterial> nextList = baseMaterialMapper.selectList(Wrappers.lambdaQuery(BaseMaterial.class)
                                    .eq(BaseMaterial::getClassType, "B")
                                    .eq(BaseMaterial::getParentBomId, allBomId)
                            );
                            if (nextList.isEmpty()){
                                mark = false;
                            }else {
                                if (nextList.size() == 1){
                                    BaseMaterial baseMaterial = nextList.get(0);
                                    //查询是否有多条数据
                                    List<BaseMaterial> nextList1 = baseMaterialMapper.selectList(Wrappers.lambdaQuery(BaseMaterial.class)
                                            .eq(BaseMaterial::getDjMaterial, baseMaterial.getDjMaterial())
                                    );
                                    if (nextList1.size() > 1){
                                        mark = false;
                                    } else {
                                        Integer nextMaSum = initStockMap.get(baseMaterial.getDjMaterial());
                                        nextMaSum = nextMaSum == null? 0 : nextMaSum;
                                        Integer baseQty = new BigDecimal(baseMaterial.getBaseQty()).intValue();
                                        //勾选
                                        if (baseMaterial.isChecked()){
                                            maSum = (nextSum * baseQty) + nextMaSum;
                                            initStockMap.put(baseMaterial.getDjMaterial(), maSum);
                                            mark = false;
                                        }else {
                                            nextSum = nextMaSum;
                                            allBomId = baseMaterial.getBomId();
                                        }
                                    }
                                } else {
                                    mark = false;
                                }
                            }
                        }
                    }
                }
            }
            List<InitialStock> list1 = new ArrayList<>();
            for (String key : initStockMap.keySet()) {
                List<BaseMaterial> materials = baseMaterialMapper.selectList(Wrappers.lambdaQuery(BaseMaterial.class)
                        .eq(BaseMaterial::getDjMaterial, key)
                );
                if (!materials.isEmpty()){
                    //判断是否勾选
                    if (!materials.get(0).isChecked()){
                        continue;
                    }
                    InitialStock stock = new InitialStock();
                    stock.setDjMaterial(key);
                    stock.setInvSum(initStockMap.get(key));
                    stock.setClassType("B");
                    stock.setUpdateTime(new Date());
                    list1.add(stock);
                }

            }
            if (type.equals("insert")){
                List<String> collect = list1.stream().map(InitialStock::getDjMaterial).collect(Collectors.toList());
                List<InitialStock> initialStocks = stockService.list(Wrappers.lambdaQuery(InitialStock.class).in(InitialStock::getDjMaterial, collect));
                if (!initialStocks.isEmpty()){
                    return R.error("已存在料号，不能重复导入！");
                }
            }else {
                //删除所有
                stockService.remove(Wrappers.lambdaUpdate(InitialStock.class));
            }
            ArrayList<InitialStock> collect = list1.stream().collect(Collectors.collectingAndThen(
                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(InitialStock::getDjMaterial))), ArrayList::new
            ));
            //添加
            stockService.saveBatch(collect);
            iStockNowService.remove(Wrappers.lambdaUpdate(StockNow.class).in(StockNow::getMaterial,initStockMap.keySet()));
            iStockNowService.initStockNowData(DateUtil.format(new Date(),"yyyy-MM-dd"));
            return R.ok().put("data", count);
        }
        return R.ok();
    }

    @RequestMapping("/download_templet")
    @ResponseBody
    public void templet(HttpServletResponse response) {
        try {
            //excel表头
            List<TitleEntity> titleList=new ArrayList<>();
            titleList.add(new TitleEntity("0",null,"初期库存导入模板",null));
            titleList.add(new TitleEntity("1","0","料号",null));
            titleList.add(new TitleEntity("2","0","库存",null));
            List<InitialStock> list = new ArrayList<>();
            ExcelTool excelTool = new ExcelTool("初期库存导入模板",20,20);
            List<Column>  titleData = excelTool.columnTransformer(titleList,"t_id","t_pid","t_content","t_fielName","0");
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("初期库存导入模板.xls", "utf-8"));
            excelTool.exportExcel(titleData,list, response.getOutputStream(),true,true);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping("/download_export")
    @ResponseBody
    public void export(HttpServletResponse response) {
        try {
            //excel表头
            List<TitleEntity> titleList=new ArrayList<>();
            titleList.add(new TitleEntity("0",null,"初期库存导出",null));
            titleList.add(new TitleEntity("1","0","料号","djMaterial"));
            titleList.add(new TitleEntity("2","0","库存","invSum"));
            List<InitialStock> initialStocks = stockService.list();
            ExcelTool excelTool = new ExcelTool("初期库存导出",20,20);
            List<Column>  titleData = excelTool.columnTransformer(titleList,"t_id","t_pid","t_content","t_fielName","0");
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("初期库存导出.xls", "utf-8"));
            excelTool.exportExcel(titleData,initialStocks, response.getOutputStream(),true,true);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    private BaseEntry setObj(BaseEntry baseEntry, String obj) throws Exception {
        if(obj.contains("[{")) {
            baseEntry.setData(BeanUtil.parseObjToList(obj, Class.forName(baseEntry.getEntityClass())));
        }else {
            baseEntry.setData(BeanUtil.parseObjToBean(obj, Class.forName(baseEntry.getEntityClass())));
        }
        return baseEntry;
    }

}

